package com.dragonlance.dao;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.log4j.Logger;
/**
 * @author Z.ting 2011-8-10 下午08:05:06
 */
public class BaseDao implements IDao {
    String url = "jdbc:mysql://localhost:3306/dl";
    String jdbcDriver = "com.mysql.jdbc.Driver";
    String user = "root";
    String password = "wickila";
	protected QueryRunner qryRun = null;
	protected Logger logger = Logger.getLogger(getClass());
	private java.sql.DatabaseMetaData dbmb;
	protected Connection conn;
	public BaseDao() {
		DbUtils.loadDriver(jdbcDriver);
		try {
			conn = DriverManager.getConnection(url, user, password);
			qryRun = new QueryRunner();
			dbmb = conn.getMetaData();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public <T extends Object> List<T> findAll(Class<T> clazz) {
		ResultSetHandler<List<T>> rsh = new BeanListHandler<T>(clazz);
		List<T> result = null;
		try {
			result = qryRun.query(conn,"select * from " + clazz.getSimpleName(), rsh);
			logger.debug("SQL: select * from " + clazz.getSimpleName());
		} catch (SQLException e) {
			logger.error("Can not this query table " + clazz.getSimpleName(), e);
		}
		return result;
	}
	@Override
	public <T> T findById(Class<T> clazz, int id) {
		ResultSetHandler<T> rsh = new BeanHandler<T>(clazz);
		T result = null;
		try {
			ResultSet rs = dbmb.getPrimaryKeys(null, null, clazz.getSimpleName());
			String primary_key = null;
			while (rs.next()) {
				primary_key = rs.getString("Column_name");
			}
			if (!"".equals(primary_key) || null != primary_key) {
				result = qryRun.query(conn,"select * from " + clazz.getSimpleName() + 
				" where " + primary_key + "=?", rsh, new Object[] { id });
				logger.debug("SQL: select * from " + clazz.getSimpleName() + " where " + 

                    primary_key + "=" + id);
			} else {
				logger.error("This table " + clazz.getSimpleName() + " has not primary key");
				throw new SQLException("This table has not primary key");
			}
		} catch (SQLException e) {
			logger.error("Can not this query table " + clazz.getSimpleName(), e);
		}
		return result;
	}
	@Override
	public List<Map<String, Object>> executeQuery(String sql, Object... args) {
		MapListHandler rsh = new MapListHandler();
		List<Map<String, Object>> result = null;
		try {
			result = qryRun.query(conn,sql, rsh, args);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	@Override
	public long insert(String sql, Object... args) {
		return executeUpdate(sql, args);
	}
	@Override
	public long update(String sql, Object... args) {
		return executeUpdate(sql, args);
	}
	@Override
	public void delete(String sql, Object... args) {
		executeUpdate(sql, args);
	}
	@Override
	public long executeUpdate(String sql, Object... args) {
		long id = 0;
		try {
			id = qryRun.update(conn,sql, args);
		} catch (SQLException e) {
			logger.error("This table can not changed !", e);
		}
		return id;
	}
	@Override
	public int[] batchUpdate(String sql, Object[][] objs) {
		int[] ids = null;
		try {
			ids = qryRun.batch(conn,sql, objs);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return ids;
	}
	
	@Override
	public <T> void save(T obj){
		
	}
}